package com.wlstock.funi.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;

import android.content.Context;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.misc.TransactionManager;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.wlstock.funi.model.OperateModel;
import com.wlstock.funi.model.SelfFundModel;
import com.wlstock.funi.model.SelfFundSetModel;
import com.wlstock.funi.utils.CaculateUtils;
import com.wlstock.funi.utils.TimeUtils;

public class SelfFundSetDao {
	private DataBaseHelper dbHelper;
	private static SelfFundSetDao daoInstance;
	private Dao<SelfFundSetModel, Integer> selfFundSetDao;
	
	@SuppressWarnings("unchecked")
	private SelfFundSetDao(Context mContext){
		try {
			dbHelper = DataBaseHelper.getHelper(mContext);
			selfFundSetDao = dbHelper.getDao(SelfFundSetModel.class);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static SelfFundSetDao getInstance(Context mContext){
		if (daoInstance == null) {
			synchronized (SelfFundSetDao.class) {
				if (daoInstance == null) {
					daoInstance = new SelfFundSetDao(mContext);
				}
			}
		}
		return daoInstance;
	}
	
	/**
	 * 批量插入
	 * @param models
	 */
	public void addOrUpdateList(final List<SelfFundSetModel> models){
		try {
			TransactionManager.callInTransaction(dbHelper.getConnectionSource(), new Callable<Void>() {

				@Override
				public Void call() throws Exception {
					for (int i = 0; i < models.size(); i++) {
						selfFundSetDao.createOrUpdate(models.get(i));
					}
					return null;
				}
			});
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	/**
	 * 查询还在待执行序列中的所有监测条件
	 * @param stkNo
	 * @param pendState
	 * @return
	 */
	public List<SelfFundSetModel> querySetByStkCode(String stkNo,int pendState){
		try {
			return selfFundSetDao.queryBuilder().where().eq("stkNo", stkNo).and().eq("pending", pendState).query();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 查询这个代码的所有设置
	 * @param stkNo
	 * @return
	 */
	public List<SelfFundSetModel> querySetByStkCode(String stkNo){
		try {
			return selfFundSetDao.queryBuilder().where().eq("stkNo", stkNo).query();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 是否需要买
	 * @param selfFundModel
	 * @param date
	 * @return
	 */
	public boolean isBuy(SelfFundModel selfFundModel,Date date) {
		return needOperate(selfFundModel, date,OperateModel.TradeType_BUY);
	}
	
	/**
	 * 是否需要卖
	 * @param sfModel
	 * @param date
	 * @return
	 */
	public boolean isSaile(SelfFundModel sfModel, Date date){
		return needOperate(sfModel, date,OperateModel.TradeType_SELL);
	}
	
	/**
	 * 是否需要操作
	 * @param selfFundModel
	 * @param date
	 * @param tradeType 
	 * @return
	 */
	private boolean needOperate(SelfFundModel selfFundModel,Date date, int tradeType) {
		List<SelfFundSetModel> result = querySetByStkCode(selfFundModel.getStockNo(),SelfFundSetModel.PENDING, tradeType);
		if (result==null || result.size()==0) {
			return false;
		}
		for (int i = 0; i < result.size(); i++) {
			SelfFundSetModel setModel = result.get(i);
			if (setModel.getPending() == SelfFundSetModel.DONE) {
				return false;
			}
			if(TimeUtils.isDayInRange(setModel.getStartDay(), setModel.getEndDay(), date)){
				if (TimeUtils.isHourInRange(setModel.getStartTime(), setModel.getEndTime(), date)) {
					if (setModel.getPrice() == SelfFundSetModel.ANY_PRICE) {
						return true;
					}else {
						//当差距在0.2%的时候返回true
						if (CaculateUtils.getFloatDisABS(selfFundModel.getCurPrice(), setModel.getPrice() ) < 0.2) {
							return true;
						}
					}
				}
			}
		}
		return false;
	}
	
	public SelfFundSetModel needOpSetModel(SelfFundModel selfFundModel,Date date, int tradeType) {
		List<SelfFundSetModel> result = querySetByStkCode(selfFundModel.getStockNo(),SelfFundSetModel.PENDING, tradeType);
		if (result==null || result.size()==0) {
			return null;
		}
		for (int i = 0; i < result.size(); i++) {
			SelfFundSetModel setModel = result.get(i);
			if (setModel.getPending() == SelfFundSetModel.DONE) {
				return null;
			}
			if(TimeUtils.isDayInRange(setModel.getStartDay(), setModel.getEndDay(), date)){
				if (TimeUtils.isHourInRange(setModel.getStartTime(), setModel.getEndTime(), date)) {
					if (setModel.getPrice() == SelfFundSetModel.ANY_PRICE || setModel.getPrice() == SelfFundSetModel.OPEN_PRICE || setModel.getPrice() == SelfFundSetModel.CLOSE_PRICE) {
						return setModel;
					}else {
						//当差距在0.2%的时候返回true
						if (CaculateUtils.getFloatDisABS(selfFundModel.getCurPrice(), setModel.getPrice() ) < 0.2) {
							return setModel;
						}
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * 查询还在待执行序列中的所有监测条件
	 * @param stkNo
	 * @param pendState
	 * @param tradeType
	 * @return
	 */
	private List<SelfFundSetModel> querySetByStkCode(String stockNo, int pending, int tradeType) {
		try {
			return selfFundSetDao.queryBuilder().where().eq("stkNo", stockNo).and().eq("pending", pending).and().eq("tradeType", tradeType).query();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 更新待执行序列状态
	 * @param stkNO
	 * @param state    查询状态
	 * @param tradeType 查询方向
	 */
	public void updatePendState(String stkNO, int state, int tradeType) {
		try {
			selfFundSetDao.updateRaw("update selffundsetmodel set pending = ? where stkno = ? and tradetype = ?", new String[]{String.valueOf(state),stkNO,String.valueOf(tradeType)});
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 一键更新队列状态
	 * @param state
	 */
	public void updatePendState(int state) {
		try {
			selfFundSetDao.updateRaw("update selffundsetmodel set pending = ?", new String[]{String.valueOf(state)});
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void createOrUpdate(SelfFundSetModel model) {
		try {
			selfFundSetDao.createOrUpdate(model);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 删除监控设置
	 * @param id
	 * @param stkNo
	 */
	public void deleteStk(int id, String stkNo) {
		DeleteBuilder<SelfFundSetModel, Integer> deleteBuilder = selfFundSetDao.deleteBuilder();
		try {
			deleteBuilder.where().eq("stkNo", stkNo).and().eq("id", id);
			deleteBuilder.delete();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 根据状态查询
	 * @param pendState
	 * @return
	 */
	public List<SelfFundSetModel> queryByState(int pendState) {
		List<SelfFundSetModel> models = new ArrayList<SelfFundSetModel>();
		try {
			models = selfFundSetDao.queryBuilder().where().eq("pending", pendState).query();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return models;
	}
	
	/**
	 * 查询所有的历史设置
	 * @return 设置列表
	 */
	public List<SelfFundSetModel> queryAll(){
		List<SelfFundSetModel> sfSetModels = null;
		try {
			sfSetModels = selfFundSetDao.queryForAll();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sfSetModels;
	}
	
	/**
	 * 查询在某个日期之前的所有的待执行的列表
	 * @param date
	 */
	public List<SelfFundSetModel> queryInvalidPendList(Date endDate){
		try {
			List<SelfFundSetModel> sfModels = selfFundSetDao.queryBuilder().where().eq("pending", SelfFundSetModel.PENDING).and().le("endDay", endDate).query();
			List<SelfFundSetModel> groupModels = selfFundSetDao.queryBuilder().groupBy("stkNo").where().eq("pending", SelfFundSetModel.PENDING).and().le("endDay", endDate).query();
			for (int i = 0; i < sfModels.size(); i++) {
				SelfFundSetModel item = sfModels.get(i);
				item.setPending(SelfFundSetModel.DONE);
				selfFundSetDao.update(item);
			}
			return groupModels;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
}
